/*
   Цифровой вольтметр, использующий 
   АЦП AD7896 от Analog Devices, 
   подключенный к AT90S8515, 
   использующий шину SPI

   CodeVisionAVR C Compiler
   (C) 2000-2002 HP InfoTech S.R.L.
   www.hpinfotech.ro

   Чип: AT90S8515
   Модель Памяти: SMALL
   Размер Стека Данных: 128 байт
   Тактовая частота: 3.6864 МГц

   Подключение AD7896 к STK500
   [AD7896] [PORTB header]
    1 Vin
    2 Vref=5V - 10 VTG
    3 AGND    - 9 GND
    4 SCLK    - 8 SCK
    5 SDATA   - 7 MISO
    6 DGND    - 9 GND
    7 CONVST  - 2 PB1
    8 BUSY    - 1 PB0
   
   Используется алфавитно-цифровой LCD 2x16, подключенный
   к разъему PORTC STK500 следующим образом:
   
   [LCD]   [РАЗЪЕМ PORTC STK500]
    1 GND - 9  GND
    2 +5V - 10 VCC
    3 VLC - управление контрастностью LCD напряжение 0..1V
    4 RS  - 1  PC0
    5 RD  - 2  PC1
    6 EN  - 3  PC2
   11 D4  - 5  PC4
   12 D5  - 6  PC5
   13 D6  - 7  PC6
   14 D7  - 8  PC7

   ПРИМЕЧАНИЕ: ПОСЛЕ ПРОГРАММИРОВАНИЯ ЧИПА ОТСОЕДИНИТЕ
   6-ЖИЛЬНЫЙ ПРОГРАММИРУЮЩИЙ КАБЕЛЬ ОТ РАЗЪЕМА SPROG3   
*/

#asm
   .equ __lcd_port=0x15
#endasm

#include <lcd.h> // драйверные программы LCD
#include <spi.h> // драйверные программы SPI
#include <90s8515.h>
#include <stdio.h>
#include <delay.h>

// опорное напряжение AD7896 [мВ]
#define VREF 5000L
// распределение битов ПОРТА B для управляющих сигналов AD7896 
#define ADC_BUSY PINB.0
#define NCONVST PORTB.1

// буфер LCD дисплея
char lcd_buffer[33];

unsigned read_adc(void)
{
   unsigned result;
   // начало преобразования в режиме 1
   // (высокое разрешение)
   NCONVST=0;
   NCONVST=1;
   // ждем окончание преобразования
   while (ADC_BUSY);
   // читаем MSB, используя SPI
   result=(unsigned) spi(0)<<8;
   // читаем LSB, используя SPI, и соединяем с MSB
   result|=spi(0);
   // вычисляем напряжение в [мВ]
   result=(unsigned) (((unsigned long) result*VREF)/4096L);
   // возвращаем измеренное напряжение
   return result;
}

void main(void)
{
   // инициализируем ПОРТ B
   // PB.0 вход для сигнала BUSY AD7896 
   // PB.1 выход для сигнала /CONVST AD7896 
   // PB.2 и PB.3 входы
   // PB.4 выход (вывод /SS SPI)
   // PB.5 вход
   // PB.6 вход (SPI MISO)
   // PB.7 выход для сигнала SCLK AD7896 
   DDRB=0x92;
   // инициализируем SPI в режиме мастера (master)
   // прерываний нет, MSB первый, фаза тактирующих импульсов
   // отрицательная
   // SCK в режиме ожидания имеет низкий уровень, фаза тактирующих
   // импульсов = 0
   // SCK=fxtal/4
   SPCR=0x54;
   // AD7896 будет работать в режиме 1
   // (высокое разрешение)
   // /CONVST=1, SCLK=0
   PORTB=2;
   // инициализируем LCD
   lcd_init(16);
   lcd_putsf("AD7896 SPI bus\nVoltmeter");
   delay_ms(2000);
   lcd_clear();
   // читаем и отображаем входное напряжение АЦП
   while (1)
   {
      sprintf(lcd_buffer,"Uadc=%4umV",read_adc());
      lcd_clear();
      lcd_puts(lcd_buffer);
      delay_ms(100);
   };
}
